home *** CD-ROM | disk | FTP | other *** search
/ Aminet 32 / Aminet 32 (1999)(Schatztruhe)[!][Aug 1999].iso / Aminet / dev / lang / Python152_Src.lha / Python152_Source / Amiga / _chkufb.c < prev    next >
C/C++ Source or Header  |  1998-12-25  |  3KB  |  171 lines

  1. RCS_ID_C="$Id: _chkufb.c,v 4.1 1994/09/29 23:09:02 jraja Exp $";
  2. /*
  3.  *      _chkufb.c - return struct ufb * from a file handle (SAS/C)
  4.  *
  5.  *      Copyright © 1994 AmiTCP/IP Group, 
  6.  *                       Network Solutions Development Inc.
  7.  *                       All rights reserved.
  8.  */
  9.  
  10. #include <ios1.h>
  11. #include <stdlib.h>
  12. #include <stdio.h>
  13. #include <errno.h>
  14. #include <bsdsocket.h>
  15. #include <sys/cdefs.h>
  16. #include <amitcp/socketbasetags.h>
  17. #include <syslog.h>
  18. #include <constructor.h>
  19. #include "libcheck.h"
  20.  
  21. extern unsigned long __fmask;
  22. extern int (*__closefunc)(int);
  23.  
  24. long ASM fdCallback(REG(d0) int fd, REG(d1) int action);
  25.  
  26. /*
  27.  * The initializator priority is just above the standard I/O, so that this
  28.  * will be called after the standard I/O is initialized
  29.  */
  30. //long __stdargs
  31. //_STI_510_install_AmiTCP_callback(void)
  32. //CONSTRUCTOR_P(install_AmiTCP_callback,510)
  33.  
  34. /*
  35. * Actually this doesn't work with Python 1.5.
  36. * You must call it after the interpreter has been initialised.
  37. */
  38. long _install_AmiTCP_callback(void)
  39. {
  40.   /* needs bsdsocket.library -- I.J. */
  41.   if(checksocketlib())
  42.   {
  43.     if (SocketBaseTags(SBTM_SETVAL(SBTC_FDCALLBACK), &fdCallback, TAG_END)) {
  44.     syslog(LOG_ERR, "Cannot install fdCallback!");
  45.  
  46.     return 1;
  47. /****
  48. #if __VERSION__ > 6 || __REVISION__ > 3
  49.     return 1;
  50. #else
  51.     exit(20);
  52. #endif
  53. ****/
  54.     }
  55.   }
  56.   else
  57.     {
  58.         PyErr_Clear();             /* don't report error if socketlib not found */
  59.     }
  60.  
  61.   /*
  62.    * Set up __closefunc (which is used at stdio cleanup)
  63.    */
  64.   __closefunc = __close;
  65.  
  66.   /*
  67.    * Set default file mask to UNIX style
  68.    */
  69.   __fmask = 0644; 
  70.  
  71.   return 0;
  72. }
  73.  
  74. long ASM SAVEDS
  75. fdCallback(REG(d0) int fd, REG(d1) int action)
  76. {
  77.   struct UFB *ufb;
  78.   int fd2;
  79.  
  80. #ifdef DEBUG
  81.   syslog(LOG_INFO, "fdCallback(fd: %d, action: %d)", fd, action);
  82. #endif
  83.  
  84.   switch (action) {
  85.   case FDCB_FREE:
  86.     ufb = __chkufb(fd);
  87.     if (ufb == NULL)
  88.       return EBADF;
  89.  
  90.     if (!(ufb->ufbflg & UFB_SOCK) && ufb->ufbflg != 0) {
  91. #ifdef DEBUG
  92.       syslog(LOG_ERR, "fdCallback: fd (%d) is not a socket!", fd);
  93. #endif
  94.       return ENOTSOCK;
  95.     }
  96.  
  97.     ufb->ufbflg = 0;
  98.     return 0;
  99.  
  100.   case FDCB_ALLOC:
  101.     do {
  102.       ufb = __allocufb(&fd2);
  103.       if (ufb == NULL)
  104.     return ENOMEM;
  105. #ifdef DEBUG
  106.       if (fd2 > fd) {
  107.     syslog(LOG_ERR, "fdCallback: fd2(%d) > fd(%d)!", fd2, fd);
  108.     return EINVAL;
  109.       }
  110. #endif
  111.       ufb->ufbflg = UFB_SOCK | UFB_WA | UFB_RA; /* read/write socket */
  112.       ufb->ufbfh = NULL; /* no file handle */
  113.       ufb->ufbfn = NULL; /* no name */
  114.     } while (fd2 < fd);
  115.     return 0;
  116.  
  117.   case FDCB_CHECK:
  118.     ufb = __chkufb(fd);
  119.     if (ufb != NULL && ufb->ufbflg != 0) 
  120.       return EBADF;
  121.     
  122.     return 0;
  123.  
  124.   default:
  125. #ifdef DEBUG
  126.     syslog(LOG_ERR, "fdCallback: invalid action.");
  127. #endif
  128.     return EINVAL;
  129.   }
  130. }
  131.  
  132.  
  133. struct UFB *
  134. __chkufb(int fd)
  135. {
  136.   struct UFB *ufb;
  137.  
  138.   /* a single element cache */
  139.   static struct UFB *last_ufb = NULL;
  140.   static int         last_fd = -1;
  141.  
  142.   _OSERR = 0;
  143.  
  144.   if ((unsigned int)fd >= __nufbs) { /* unsigned cast checks for (fd < 0) */
  145.     errno = EBADF;
  146.     return NULL;
  147.   }
  148.  
  149.   /*
  150.    * Check the cache first
  151.    */
  152.   if (fd == last_fd)
  153.     return last_ufb;
  154.  
  155.   last_fd = fd; /* update cache */
  156.   ufb = __ufbs;
  157.   while (fd > 0 && ufb != NULL) {
  158.     fd--;
  159.     ufb = ufb->ufbnxt;
  160.   }
  161.   last_ufb = ufb; /* update cache */
  162.   
  163.   if (ufb == NULL) {
  164.     last_fd = -1; /* invalidate cache */
  165.     errno = EIO;
  166.     return NULL;
  167.   }
  168.   else
  169.     return ufb;
  170. }
  171.